import {
    assign,
    forEach,
    isArray
  } from "min-dash";
  
  import {
    is
  } from "bpmn-js/lib/util/ModelUtil";
  
  import {
    isAny
  } from "bpmn-js/lib/features/modeling/util/ModelingUtil";
  
  import {
    hasPrimaryModifier
  } from "diagram-js/lib/util/Mouse";
  
  export default function ContextPadProvider(
    config,
    injector,
    eventBus,
    contextPad,
    modeling,
    elementFactory,
    connect,
    create,
    popupMenu,
    canvas,
    rules,
    translate,
    elementRegistry
  ) {
    config = config || {};
  
    contextPad.registerProvider(this);
  
    this._contextPad = contextPad;
    this._modeling = modeling;
    this._elementFactory = elementFactory;
    this._connect = connect;
    this._create = create;
    this._popupMenu = popupMenu;
    this._canvas = canvas;
    this._rules = rules;
    this._translate = translate;
  
    if (config.autoPlace !== false) {
      this._autoPlace = injector.get("autoPlace", false);
    }
  
    eventBus.on("create.end", 250, function (event) {
      var context = event.context,
        shape = context.shape;
  
      if (!hasPrimaryModifier(event) || !contextPad.isOpen(shape)) {
        return;
      }
  
      var entries = contextPad.getEntries(shape);
  
      if (entries.replace) {
        entries.replace.action.click(event, shape);
      }
    });
  }
  
  ContextPadProvider.$inject = [
    "config.contextPad",
    "injector",
    "eventBus",
    "contextPad",
    "modeling",
    "elementFactory",
    "connect",
    "create",
    "popupMenu",
    "canvas",
    "rules",
    "translate",
    "elementRegistry"
  ];
  
  ContextPadProvider.prototype.getContextPadEntries = function (element) {
    var contextPad = this._contextPad,
      modeling = this._modeling,
      elementFactory = this._elementFactory,
      connect = this._connect,
      create = this._create,
      popupMenu = this._popupMenu,
      canvas = this._canvas,
      rules = this._rules,
      autoPlace = this._autoPlace,
      translate = this._translate;
  
    var actions = {};
  
    if (element.type === "label") {
      return actions;
    }
  
    var businessObject = element.businessObject;
  
    function startConnect(event, element) {
      connect.start(event, element);
    }
  
    function removeElement() {
      modeling.removeElements([element]);
    }
  
  
  
    /**
     * Create an append action
     *
     * @param {string} type
     * @param {string} className
     * @param {string} [title]
     * @param {Object} [options]
     * @return {Object} descriptor
     */
    function appendAction(type, className, title, options) {
      if (typeof title !== "string") {
        options = title;
        title = translate("Append {type}", {
          type: type.replace(/^bpmn:/, "")
        });
      }
  
      function appendStart(event, element) {
        var shape = elementFactory.createShape(assign({
          type: type
        }, options));
        create.start(event, shape, {
          source: element
        });
      }
  
      var append = autoPlace ?
        function (event, element) {
          var shape = elementFactory.createShape(assign({
            type: type
          }, options));
  
          autoPlace.append(element, shape);
        } :
        appendStart;
  
      return {
        group: "model",
        className,
        title,
        action: {
          dragstart: appendStart,
          click: append
        }
      };
    }
  
  
    if (is(businessObject, "bpmn:FlowNode")) {
  
      if (
        !is(businessObject, "bpmn:EndEvent")
      ) {
        assign(actions, {
          "append.append-task": appendAction("bpmn:UserTask", "icon-custom taskNode", translate("Append Task")),
          "append.gateway": appendAction("bpmn:ExclusiveGateway", "icon-custom gatewayNode", translate("Append Gateway")),
          "append.end-event": appendAction("bpmn:EndEvent", "icon-custom endNode", translate("Append EndEvent")),
        });
      }
    }
  
    if (isAny(businessObject, ["bpmn:FlowNode", "bpmn:InteractionNode", "bpmn:DataObjectReference", "bpmn:DataStoreReference"])) {
      assign(actions, {
  
        connect: {
          group: "edit",
          // className: "bpmn-icon-connection-multi",
          className: "feelec feel-lianxian",
          title: translate("Connect using " + (businessObject.isForCompensation ? "" : "Sequence/MessageFlow or ") + "Association"),
          action: {
            click: startConnect,
            dragstart: startConnect
          }
        }
      });
    }
  
  
  
    // delete element entry, only show if allowed by rules
    var deleteAllowed = rules.allowed("elements.delete", {
      elements: [element]
    });
  
    if (isArray(deleteAllowed)) {
      // was the element returned as a deletion candidate?
      deleteAllowed = deleteAllowed[0] === element;
    }
  
    if (deleteAllowed) {
      assign(actions, {
        delete: {
          group: "edit",
          className: "bpmn-icon-trash",
          title: translate("Remove"),
          action: {
            click: removeElement
          }
        }
      });
    }
    return actions;
  };
  